/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package jumavidesktop.Manejadores.Implementaciones;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import jumavidesktop.Manejadores.Intefaces.INotificadoContrCam;
import jumavidesktop.Manejadores.Intefaces.INotificadoMatricula;
import jumavidesktop.Manejadores.Intefaces.INotificadoVideo;
import jumavidesktop.Manejadores.Intefaces.ISubjectVideo;
import jumavidesktop.Otros.Pojos.MyRespuesta;
import jumavidesktop.Persistencia.Dao.Implementaciones.DaoCamaras;
import jumavidesktop.Persistencia.Dao.Interfaces.IDaoCamaras;
import jumavidesktop.Persistencia.entidades.Camara;

/**
 *
 * @author kjh
 */
public class ControlMCamaras implements INotificadoContrCam, ISubjectVideo{
    Map<String,MCamara> camaras;
    List<INotificadoMatricula> detectoresMatricula;  
    List<INotificadoVideo> detectoresVideo;
    MCamara camActual;
    IDaoCamaras dao = new DaoCamaras();
    
    public ControlMCamaras(){
        camaras = new HashMap<>();
        detectoresMatricula = new ArrayList<>();
        detectoresVideo = new ArrayList<>();
        camActual = null;
        this.setMCamaras(dao.obtenerCamarasActivas());
    }
    
    public ControlMCamaras(List<INotificadoMatricula> detectores){
        this();
        agregarObservadores(detectores);
    }
    
    public MCamara getCamaraActual(){
        return camActual;
    }
    
    public void setCamaraActual(MCamara cam){
        camActual = cam;
    }
    
    public MCamara getMCamara(String nombre){
        return camaras.get(nombre);
    }
    
    public int getSize(){
        return camaras.size();
    }
    
    public Set<String> getNombresCamaras(){
        return camaras.keySet();
    }
    
    
    
    public MyRespuesta setMCamara(Camara cam){
        MCamara camara = new MCamara(cam);
        MyRespuesta res = new MyRespuesta();
        if(camaras.containsKey(camara.getCamara().getNombre())) {
            res.addError("Esta cámara ya existe");
        }
        else{
            camara.agregarDetectores(detectoresMatricula);
            camaras.put(camara.getCamara().getNombre(), camara);
        }
        return res;
    }
    
    public MyRespuesta setMCamaras(List<Camara> lista){
        MyRespuesta res = new MyRespuesta();
        for(Camara cam: lista){
            res = this.setMCamara(cam);
        }
        return res;
    }
    
    public void removeMCamara(Camara camara){
        camaras.remove(camara.getNombre());
    }
    
    public void agregarObservador(INotificadoMatricula detector){
        detectoresMatricula.add(detector);
        for(MCamara cam : camaras.values()){
            cam.attach(detector);
        }
    }
    
    public void agregarObservadores(List<INotificadoMatricula> detectores){
        for(INotificadoMatricula not: detectores){
            agregarObservador(not);
        }
    }
    
        
    public void eliminarObservador(INotificadoMatricula detector){
        detectoresMatricula.remove(detector);
        for(MCamara cam : camaras.values()){
            cam.dettach(detector);
        }
    }
    
    public void eliminarObservadores(List<INotificadoMatricula> detectores){
        for(INotificadoMatricula not: detectores){
            eliminarObservador(not);
        }
    }
    


    @Override
    public void updateCam(Camara cam, boolean llave) {
        if(llave){
            //guardo en mi lista de cámaras, y aviso al vídeo de cámara nueva.
            this.setMCamara(cam);
            this.notificarObservadoresVideo(cam, llave);
            
        }else{
            //elimino de mi lista de cámaras, y aviso al video de quitar cámara.
            this.removeMCamara(cam);
            this.notificarObservadoresVideo(cam, llave);
        }
    }

    @Override
    public void attachVideo(INotificadoVideo cont) {
        this.detectoresVideo.add(cont);
    }

    @Override
    public void dettachVideo(INotificadoVideo cont) {
        this.detectoresVideo.remove(cont);
    }

    @Override
    public void notificarObservadoresVideo(Camara cam, boolean llave) {
        for (INotificadoVideo item : detectoresVideo) {
            item.updateCam(cam, llave);
        } 
    }
    
}
